using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Framework;

namespace Battle.Graphics
{
    public interface IActorGraphic
    {
        int Id { get; set; }
        void OnCreate(GameObject gameObject,YooAsset.AssetHandle handle);
        void Update();
        void OnDestroy();
    }

    public class ActorManager : MonoBehaviour
    {
        public static ActorManager Instance { get; private set; }
        private void Awake()
        {
            Instance = this;
            mActors = new Dictionary<int, IActorGraphic>(128);

            EventDispatchManager.Instance.AddEvent(EventId.Battle.Graphic.EVENT_CREATE_ACTOR, OnEventCreateActor);
        }

        private void Update()
        {
            foreach(var actor in mActors.Values)
            {
                actor.Update();
            }
        }

        void OnEventCreateActor(IEventArgv eventArgv)
        {
            if(eventArgv is EventArgv<int,int> argv)
            {

            }
        }

        private void OnDestroy()
        {
            EventDispatchManager.Instance.RemoveEvent(EventId.Battle.Graphic.EVENT_CREATE_ACTOR, OnEventCreateActor);
            Instance = null;
        }

        Dictionary<int, IActorGraphic> mActors;

        public void Add<T>(int id,string path, string package = "DefaultPackage") where T : class,IActorGraphic,new()
        {
            if(mActors.ContainsKey(id))
            {
                SLogger.E($"Actor Id={id} Repeated");
                return;
            }

            if(string.IsNullOrEmpty(path))
            {
                SLogger.E("Create Actor Failed Path Can Not Be Empty");
                return;
            }

            if(string.IsNullOrEmpty(package))
            {
                SLogger.E("Create Actor Failed Package Can Not Be Empty");
                return;
            }

            var pkg = YooAsset.YooAssets.GetPackage(package);
            if (null == pkg)
            {
                SLogger.E($"Package Which Named {package} Not Be Founded");
                return;
            }

            var handle = pkg.LoadAssetSync<GameObject>(path);
            if(null == handle)
            {
                SLogger.E($"Load Asset Failed Package={package} path={path}");
                return;
            }

            var objHandle = (GameObject)Object.Instantiate(handle.AssetObject, gameObject.transform, false);

            T actor = new T();
            actor.Id = id;
            mActors.Add(id, actor);

            try
            {
                actor.OnCreate(objHandle, handle);
            }
            catch(System.Exception e)
            {
                SLogger.E(e.Message);
            }
        }

        public IActorGraphic Get(int id)
        {
            if(mActors.TryGetValue(id, out var actor))
            {
                return actor;
            }
            return null;
        }

        public T Get<T>(int id) where T : class, IActorGraphic, new()
        {
            if (mActors.TryGetValue(id, out var actor))
            {
                return actor as T;
            }
            return null;
        }

        public void Remove(int id)
        {
            if(mActors.TryGetValue(id, out var actor))
            {
                mActors.Remove(id);
                actor.OnDestroy();
            }
        }
    }
}
